home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Hot Pics! - Vol. Sex!
/
Hot Pics - Vol Sex.iso
/
amiga
/
anim
/
ilbmwx.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-05-06
|
7KB
|
211 lines
/*----------------------------------------------------------------------*
* ILBMW.C Support routines for writing ILBM files. 1/23/86
* (IFF is Interchange Format File.)
*
* revised for VideoStage animation IFF files by Gary Bonham,
* Sparta Inc., 15 Aug 86.
*
* By Jerry Morrison and Steve Shaw, Electronic Arts.
* This software is in the public domain.
*
* This version for the Commodore-Amiga computer.
*----------------------------------------------------------------------*/
#include "functions.h"
#include "packer.h"
#include "ilbm.h"
#include "stdio.h"
#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)<(b)?(a):(b))
extern int Pop;
UBYTE BMmask;
/*---------- InitBMHdr -------------------------------------------------*/
IFFP InitBMHdr(bmHdr0, bitmap, masking, compression, transparentColor,
pageWidth, pageHeight)
BitMapHeader *bmHdr0; struct BitMap *bitmap;
WORD masking; /* Masking */
WORD compression; /* Compression */
WORD transparentColor; /* UWORD */
WORD pageWidth, pageHeight;
{
register BitMapHeader *bmHdr = bmHdr0;
register WORD rowBytes = bitmap->BytesPerRow;
long maxx,minx,maxy,miny,ip,ib,ir;
bmHdr->w = rowBytes << 3;
bmHdr->h = bitmap->Rows;
bmHdr->x = bmHdr->y = 0; /* Default position is (0,0).*/
bmHdr->nPlanes = bitmap->Depth;
bmHdr->masking = masking;
bmHdr->compression = compression;
bmHdr->pad1 = 0;
bmHdr->transparentColor = transparentColor;
bmHdr->xAspect = bmHdr->yAspect = 1;
bmHdr->pageWidth = pageWidth;
bmHdr->pageHeight = pageHeight;
BMmask = 0xFF;
if (Pop) {
maxx = 0;
minx = 10000;
maxy = 0;
miny = 10000;
BMmask = 0;
for (ip=0;ip<bitmap->Depth;ip++) {
for (ir=0;ir<bitmap->Rows;ir++) {
for (ib=0;ib<rowBytes;ib++) {
if (*(bitmap->Planes[ip]+ib+ir*rowBytes)) {
BMmask |= 1<<ip;
maxx = MAX(maxx,ib);
minx = MIN(minx,ib);
maxy = MAX(maxy,ir);
miny = MIN(miny,ir);
}
}
}
}
if (BMmask == 0) {
minx = 0;
miny = 0;
maxx = rowBytes - 1;
maxy = bitmap->Rows - 1;
}
rowBytes = maxx - minx + 1;
if (rowBytes & 1) {
rowBytes++;
if (minx & 1) minx--;
else maxx++;
}
bmHdr->x = minx << 3;
bmHdr->y = miny;
bmHdr->w = rowBytes << 3;
bmHdr->h = maxy - miny + 1;
}
if (pageWidth < 400) {
if (pageHeight < 300) {
bmHdr->xAspect = x320x200Aspect;
bmHdr->yAspect = y320x200Aspect;
}
else {
bmHdr->xAspect = x320x400Aspect;
bmHdr->yAspect = y320x400Aspect;
}
}
else {
if (pageHeight < 300) {
bmHdr->xAspect = x640x200Aspect;
bmHdr->yAspect = y640x200Aspect;
}
else {
bmHdr->xAspect = x640x400Aspect;
bmHdr->yAspect = y640x400Aspect;
}
}
return( IS_ODD(rowBytes) ? CLIENT_ERROR : IFF_OKAY );
}
/*---------- PutCMAP ---------------------------------------------------*/
IFFP PutCMAP(context, colorMap, depth)
GroupContext *context; WORD *colorMap; UBYTE depth;
{
register LONG nColorRegs;
IFFP iffp;
ColorRegister colorReg;
if (depth > 5) depth = 5;
nColorRegs = 1 << depth;
iffp = PutCkHdr(context, ID_CMAP
, (long)(nColorRegs * sizeofColorRegister));
CheckIFFP();
for ( ; nColorRegs; --nColorRegs) {
colorReg.red = ( *colorMap >> 4 ) & 0xf0;
colorReg.green = ( *colorMap ) & 0xf0;
colorReg.blue = ( *colorMap << 4 ) & 0xf0;
iffp = IFFWriteBytes(context, (BYTE *)&colorReg
, (long)sizeofColorRegister);
CheckIFFP();
++colorMap;
}
iffp = PutCkEnd(context);
return(iffp);
}
/*---------- PutBODY ---------------------------------------------------*/
/* NOTE: This implementation could be a LOT faster if it used more of the
* supplied buffer. It would make far fewer calls to IFFWriteBytes (and
* therefore to DOS Write). */
IFFP PutBODY(context, bitmap, mask, bmHdr, buffer, bufsize)
GroupContext *context; struct BitMap *bitmap; BYTE *mask;
BitMapHeader *bmHdr; BYTE *buffer; LONG bufsize;
{
IFFP iffp;
LONG rowBytes = bitmap->BytesPerRow;
long dstDepth = bmHdr->nPlanes;
Compression compression = bmHdr->compression;
long planeCnt; /* number of bit planes including mask */
long deltabyte;
register long iPlane, iRow;
register LONG packedRowBytes;
BYTE *buf;
BYTE *planes[MaxAmDepth + 1]; /* array of ptrs to planes & mask */
deltabyte = (bmHdr->pageWidth>>3) - (bmHdr->w>>3);
if ( bufsize < MaxPackedSize(rowBytes) || /* Must buffer a comprsd row*/
compression > cmpByteRun1 || /* bad arg */
bitmap->Depth < dstDepth || /* inconsistent */
dstDepth > MaxAmDepth ) /* too many for this routine*/
return(CLIENT_ERROR);
planeCnt = dstDepth + (mask == NULL ? 0 : 1);
/* Copy the ptrs to bit & mask planes into local array "planes" */
for (iPlane = 0; iPlane < dstDepth; iPlane++)
if ((Pop == 0) || ((BMmask>>iPlane)&1))
planes[iPlane] = (BYTE *)bitmap->Planes[iPlane]
+ bmHdr->y * rowBytes + (bmHdr->x>>3);
else planes[iPlane] = NULL;
#if 0
printf("plane %ld: %ld %ld\n",iPlane,planes[iPlane],bitmap->Planes[iPlane]);
#endif
if (mask != NULL) planes[dstDepth] = mask;
/* Write out a BODY chunk header */
iffp = PutCkHdr(context, ID_BODY, (long)szNotYetKnown);
CheckIFFP();
/* Write out the BODY contents */
for (iRow = bmHdr->h; iRow > 0; iRow--) {
for (iPlane = 0; iPlane < planeCnt; iPlane++) {
if (planes[iPlane]) {
/* Write next row.*/
if (compression == cmpNone) {
iffp = IFFWriteBytes(context, planes[iPlane], (long)rowBytes);
planes[iPlane] += rowBytes;
}
/* Compress and write next row.*/
else {
buf = buffer;
packedRowBytes = PackRow(&planes[iPlane], &buf
, (long)(bmHdr->w>>3));
iffp = IFFWriteBytes(context, buffer, (long)packedRowBytes);
planes[iPlane] += deltabyte;
}
}
CheckIFFP();
}
}
/* Finish the chunk */
iffp = PutCkEnd(context);
return(iffp);
}